﻿using System;
using System.Collections.ObjectModel;
using System.IO;
using AgFx;
using DepSoft.Mobile.WP7.FollwIt.Framework;
using DepSoft.Mobile.WP7.FollwIt.Model;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace DepSoft.Mobile.WP7.FollwIt.ViewModel
{
    /// <summary>
    /// We cache a Movie Collection for 1 hour ( 3600 secs )
    /// We do a cache then refresh, because this will give us following principle
    /// 1. App will make request, [A, B, C] will be returned from cache and displayed
    /// 2. AgFx will see that the cache is no longer valid (more than 3600 seconds have elapsed) and will kick off a new request
    /// 3. Server will return, say [C, D, E]
    /// 4. Cache will be replaced and UI will bind to new value 
    /// </summary>
    [CachePolicy(CachePolicy.CacheThenRefresh, 3600)]
    public class agfxTVShowCollectionViewModel : ModelItemBase<TVShowCollectionLoadContext>
    {
        #region Public bindable properties
        public const string TVShowsPropertyName = "TVShows";
        private BatchObservableCollection<TVShow> _tvShows = new BatchObservableCollection<TVShow>();

        public ObservableCollection<TVShow> TVShows
        {
            get
            {
                return _tvShows;
            }
            set
            {
                if (!ReferenceEquals(_tvShows, null))
                {
                    _tvShows.Clear();

                    if (_tvShows != value)
                    {
                        foreach (var tvShow in value)
                        {
                            _tvShows.Add(tvShow);
                        }
                    }
                }
                RaisePropertyChanged(TVShowsPropertyName);
            }
        }
        #endregion

        #region Constructor
        public agfxTVShowCollectionViewModel()
        {

        }

        public agfxTVShowCollectionViewModel(string userName)
            : base(new TVShowCollectionLoadContext(userName))
        {

        }
        #endregion

        #region AgFx DataLoader
        public class agfxTVShowCollectionViewModelLoader : IDataLoader<TVShowCollectionLoadContext>
        {
            #region IDataLoader implementation
            public object Deserialize(TVShowCollectionLoadContext loadContext, Type objectType, Stream stream)
            {
                agfxTVShowCollectionViewModel viewModel = new agfxTVShowCollectionViewModel(loadContext.UserName);
                var sr = new StreamReader(stream);
                var tvShowCollectionJSON = sr.ReadToEnd();
                try
                {
                    JArray tvShowCollection = JArray.Parse(tvShowCollectionJSON);

                    JsonSerializer serializer = new JsonSerializer();
                    foreach (JToken tvShowJSON in tvShowCollection)
                    {
                        TVShow tvShow = (TVShow)serializer.Deserialize(new JTokenReader(tvShowJSON), typeof(TVShow));

                        viewModel.TVShows.Add(tvShow);
                    }
                }
                catch (Exception e)
                {
                    //JObject errorParsed = JObject.Parse(tvShowCollectionJSON);
                    //throw new TVShowLoadException(string.Concat("Error while loading TV Show Collection", Environment.NewLine, "Reason: ", errorParsed["message"]));

                    if (!ReferenceEquals(tvShowCollectionJSON, null))
                        throw new TVShowLoadException(string.Concat("Error while loading TV Show Collection", Environment.NewLine, tvShowCollectionJSON), e);
                    else
                        throw new TVShowLoadException("Error while loading TV Show Collection", e);
                }

                return viewModel;
            }

            public LoadRequest GetLoadRequest(TVShowCollectionLoadContext loadContext, Type objectType)
            {
                return new WebLoadRequest(loadContext, new Uri(FollwItApi.GetInstance().GetActionRestURI(RestAction.GetTVShowCollection, loadContext.UserName)));
            }
            #endregion
        }
        #endregion
    }
}
